/*
 *
 * 	2009-04-05:	NEW: get_current_obj() - returns an object of the current history hash
 *
 */
liwe.history = {};

liwe.history.listener_callback = {};

liwe.history.cbacks = {
	"before-add" : null,
	"before-module" : null
};

liwe.history._load = function ()
{
	liwe.history._is_ie = ( document.all && navigator.userAgent.toLowerCase().indexOf ( 'msie' ) != -1 );

	liwe.history._blank_page = liwe._libbase + "/data/history_blank.html";

	liwe.history._data_storage = [];
	
	if ( liwe.history._is_ie )
		liwe.history._int_create_iframe ();

	document.write ( '<form style="display: none;"><input id="historyDataText" type="text" value="" \/><\/form>' );
};

liwe.history.init = function ()
{
	liwe.history._saved_location = liwe.history.get_current_location();

	setInterval ( liwe.history._int_check_location, 100 );

	setTimeout ( liwe.history._init_done, 200 );
};


liwe.history._init_done = function ()
{
	var hdt = document.getElementById ( "historyDataText" );
	
	if ( hdt.value )
		liwe.history._data_storage  = hdt.value.parseJSON();

	liwe.history._int_call_listener();
};


liwe.history._int_create_iframe = function ()
{
	var loc = liwe.history.get_current_location();
	
	liwe.history._adding = true;
	
	document.write ( "<iframe style='border: 2px; width: 1px; "
                               + "height: 1px; position: absolute; bottom: 0px; "
                               + "right: 0px; display: none;' "
                               + "name='liwe.historyFrame' id='liwe.historyFrame' src='" + liwe.history._blank_page + "?" + loc + "'>"
                               + "<\/iframe>" );

	liwe.history._iframe = document.getElementById ( "liwe.historyFrame" );

	window._os3_history_cb = liwe.history._int_iframe_location_changed;
};


liwe.history.get_current_location = function ()
{
	var loc = window.location.hash;
	if ( loc.length > 0 && loc.charAt ( 0 ) == '#' )
		loc = loc.slice ( 1 );
	return loc;
};

liwe.history.get_current_obj = function ()
{
	var loc = liwe.history.get_current_location ().split ( "," );
	var t, l = loc.length;
	var res = {}, tok, k, v, i;

	for ( t = 0; t < l; t ++ )
	{
		tok = loc [ t ];
		i = tok.indexOf ( '=' );
		//p = loc [ t ].split ( "=" );
		k = tok.substr ( 0, i );
		v = tok.substr ( i + 1 );
		res [ k ] = v;
	}

	return res;
};


liwe.history._int_call_listener = function ()
{
	if ( ! liwe.history.listener_callback ) return;

	var id = liwe.history.get_current_location ();
	var dict = liwe.history._str2dict ( id );
	var data, module;

	if ( typeof dict [ "__dk" ] != "undefined" )
	{
		var key = parseInt ( dict [ "__dk" ], 10 );
		data = liwe.history._data_storage [ key ];
		liwe.history._curr_dk = key;
		delete dict [ "__dk" ];
	}

	if ( typeof dict [ "__m" ] != "undefined" )
		module = dict [ "__m" ];
	else
		module = "__DEFAULT__";

	if ( ! liwe.history.listener_callback [ module ] ) return;

	liwe.history._listener_call = true;
	try
	{
		liwe.history.listener_callback [ module ] ( dict, data );
	}
	finally
	{
		liwe.history._listener_call = false;
	}
};


liwe.history.set_listener = function ( listener, module )
{
	if ( ! module ) module = "__DEFAULT__";
	liwe.history.listener_callback [ module ] = listener;
};


liwe.history.add = function ( dict, data )
{
	return liwe.history.add_module ( null, dict, data );
};

liwe.history.set_data = function ( data )
{
	liwe.history._data_storage [ liwe.history._curr_dk ] = data;
	liwe.history._write_data_storage ();

	return true;
};

liwe.history.add_module = function ( module, dict, data )
{
	if ( ! dict ) dict = {};

	if ( liwe.history._listener_call ) return;
	if ( dict.get ( "__nh" ) == 1 ) return;

	if ( liwe.history.cbacks [ 'before-add' ] )
	{
		// NOTE: function should return TRUE to block event propagation
		var block = liwe.history.cbacks [ 'before-add' ] ( module, dict, data );

		if ( block ) return;
	}

	if ( data )
	{
		var key = liwe.history._data_storage.length.toString();
		liwe.history._data_storage.push ( data );
		dict [ "__dk" ] = key;

		liwe.history._write_data_storage ();
	}

	if ( module ) dict [ "__m" ] = module;

	var id = liwe.history._dict2str ( dict );
	window.location.hash = id;
	liwe.history._saved_location = id;

	if ( liwe.history._is_ie )
	{
		liwe.history._adding = true;
		liwe.history._iframe.src = liwe.history._blank_page + "?" + id;
	}
};

liwe.history._write_data_storage = function ()
{
	var s = liwe.history._data_storage.toJSONString();
	var is = document.getElementById ( "historyDataText" );
	is.value = s;
};


liwe.history.replace = function ( module, dict, data )
{
	if ( liwe.history._listener_call ) return;

	if ( dict.get ( "__nh" ) == 1 ) return;

	var key = (liwe.history._data_storage.length - 1).toString();
	liwe.history._data_storage [ liwe.history._data_storage.length - 1 ] = data;
	dict [ "__dk" ] = key;

	var s = liwe.history._data_storage.toJSONString();
	var is = document.getElementById ( "historyDataText" );
	is.value = s;

	if ( module ) dict [ "__m" ] = module;

	var loc = String ( location ).split ( '#' ) [ 0 ];
	var id = liwe.history._dict2str ( dict );
	window.location.replace ( loc + "#" + id );
	liwe.history._saved_location = id;

	if ( liwe.history._is_ie )
	{
		liwe.history._adding = true;
		liwe.history._iframe.src = liwe.history._blank_page + "?" + id;
	}
};


liwe.history._dict2str = function ( dict )
{
	var str = "";
	var is_first = true;
	
	var k, v;
	for ( k in dict )
	{
		v = dict [ k ];
		if ( typeof ( v ) == 'function' ) continue;
		if ( v == '' ) continue;

		if ( is_first ) is_first = false;
		else str += ",";
		
		str += k;
		if ( v != null && v != undefined )
		{
			v = v.toString();
			str += "=" + liwe.history._escape_value ( v );
		}

	}

	return str;
};


liwe.history._str2dict = function ( str )
{
	var tok;

	var dict = {};

	str = liwe.history._lstrip ( str );

	while ( str.length > 0 )
	{
		// cerco la virgola divisoria
		var cpos = str.indexOf ( "," );
		while ( cpos < str.length - 1 && str.charAt ( cpos + 1 ) == ',' )
			cpos = str.indexOf ( ",", cpos + 2 );

		if ( cpos == -1 )
		{
			tok = str;

			str = "";
		} else {
			tok = str.slice ( 0, cpos );

			str = str.slice ( cpos + 1 );
			str = liwe.history._lstrip ( str );
		}

		// splittiamo sull'uguale
		var splt = tok.split ( "=" );
		var k = splt [ 0 ];
		var v = liwe.history._join ( "=", splt.slice ( 1 ) );
		v = v.replace ( ",,", "," );

		dict [ k ] = unescape(v);
	}

	return dict;
};


liwe.history._escape_value = function ( v )
{
	return v.replace ( ",", ",," );
};


liwe.history._lstrip = function ( s )
{
	while ( s.length > 0 && s.charAt ( 0 ) == ' ' )
		s = s.slice ( 1 );

	return s;
};


liwe.history._join = function ( sep, arr )
{
	var l = arr.length;
	if ( l == 0 ) return "";
	
	var s = arr [ 0 ];
	for ( var i = 1; i < l ; i++ )
		s += sep + arr [ i ];

	return s;
};


liwe.history._int_iframe_location_changed = function ( id )
{
	if ( liwe.history._adding )
	{
		liwe.history._adding = false;
		return;
	}

	if ( id.length > 0 && id.charAt ( 0 ) == '?' )
		id = id.slice ( 1 );

	window.location.hash = id;
	liwe.history._saved_location = id;

	liwe.history._int_call_listener ();
};


liwe.history._int_check_location = function ()
{
	var loc = liwe.history.get_current_location();
	if ( loc == liwe.history._saved_location )
		return;

	liwe.history._saved_location = loc;

	if ( liwe.history._is_ie )
		liwe.history._iframe.src = liwe.history._blank_page + "?" + loc;
	else
		liwe.history._int_call_listener();
};

liwe.history._load();
